package robocup.testing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.LinkedList;

import robocup.component.actions.KickAction;
import robocup.component.geometry.Vektor;
import robocup.component.geometry.analysers.PossibleBallsAfterPoweredAcc;
import robocup.component.worldobjects.Ball;
import robocup.component.worldobjects.Player;


/**
 * @author Thomas Karbe
 *
 * Tests the class PossiblePoweredBalls
 */
public class TestPoweredBalls
    extends GraphicalTestFrame {
  
  Player p= rand.getRandomPlayer();
  Ball b= rand.getRandomBallInKickable(p);
  PossibleBallsAfterPoweredAcc possBalls= new PossibleBallsAfterPoweredAcc();
  KickAction kick= new KickAction(0,0);
  Ball b1= Ball.getDummyInstance();
  Ball b2= Ball.getDummyInstance();
  Ball b3= Ball.getDummyInstance();
  Ball b4= Ball.getDummyInstance();
  Ball b5= Ball.getDummyInstance();
  LinkedList<Vektor> list= new LinkedList<Vektor>();
  double needed= 0;

  /**
   * 
   */
  public TestPoweredBalls() {

    super();
  }

  /**
   * @param d
   */
  public TestPoweredBalls(
      Dimension d) {

    super(d);
  }

  /**
   * @param center
   */
  public TestPoweredBalls(
      Vektor center) {

    super(center);
  }

  /**
   * @param d
   * @param center
   */
  public TestPoweredBalls(
      Dimension d,
      Vektor center) {

    super(d, center);
  }

  /**
   * @param scale
   */
  public TestPoweredBalls(
      double scale) {

    super(scale);
  }

  /**
   * @param d
   * @param scale
   */
  public TestPoweredBalls(
      Dimension d,
      double scale) {

    super(d, scale);
  }

  /**
   * @param center
   * @param scale
   */
  public TestPoweredBalls(
      Vektor center,
      double scale) {

    super(center, scale);
  }

  /**
   * @param d
   * @param center
   * @param scale
   */
  public TestPoweredBalls(
      Dimension d,
      Vektor center,
      double scale) {

    super(d, center, scale);
  }

  /** (non-Javadoc)
   * @see robocup.testing.GraphicalTestFrame#nextSituation()
   */
  @Override
  protected void nextSituation() {
    list= new LinkedList<Vektor>();
    p= rand.getRandomPlayer();
    setCenter(p.getPosition());
    b= rand.getRandomBallInKickable(p);
    kick.setPower(rand.getRandomDouble(0, 100));
    possBalls.setParams(p, b, kick);
    try {
      double dir= possBalls.getKickDirForResultingAngle(0);
      System.out.println("dir for ang 0: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b1.copy(b);
        b1.predictThisAfterAction(p, kick);
        System.out.println("real result: "+b.getAngleTo(b1));
        list.add(possBalls.getPointForShotAngleAbs(0));
      }
      else {
        System.out.println("dir not possible");
      }
      dir= possBalls.getKickDirForResultingAngle(90);
      System.out.println("dir for ang 90: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b2.copy(b);
        b2.predictThisAfterAction(p, kick);
        System.out.println("real result: "+b.getAngleTo(b2));
        list.add(possBalls.getPointForShotAngleAbs(90));        
      }
      else {
        System.out.println("dir not possible");
      }
      dir= possBalls.getKickDirForResultingAngle(180);
      System.out.println("dir for ang 180: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b3.copy(b);
        b3.predictThisAfterAction(p, kick);
        System.out.println("real result: "+b.getAngleTo(b3));
        list.add(possBalls.getPointForShotAngleAbs(180));   
      }
      else {
        System.out.println("dir not possible");
      }
      dir= possBalls.getKickDirForResultingAngle(-90);     
      System.out.println("dir for ang -90: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b4.copy(b);
        b4.predictThisAfterAction(p, kick);
        System.out.println("real result: "+b.getAngleTo(b4));
        list.add(possBalls.getPointForShotAngleAbs(-90));        
      }
      else {
        System.out.println("dir not possible");
      }
      needed= rand.getRandomDouble(-180, 180);
      dir= possBalls.getKickDirForResultingAngle(needed);
      System.out.println("dir for ang "+needed+": "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b5.copy(b);
        b5.predictThisAfterAction(p, kick);
        System.out.println("real result: "+b.getAngleTo(b5));
        list.add(possBalls.getPointForShotAngleAbs(needed));        
      }
      else {
        System.out.println("dir not possible");
      }
      System.out.println();
      System.out.println(p);
      System.out.println(b);
      System.out.println(kick);
      System.out.println(possBalls);
      System.out.println(list);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /** (non-Javadoc)
   * @see robocup.testing.GraphicalTestFrame#nextCycle()
   */
  @Override
  protected void nextCycle() {
    list.clear();
    possBalls.extrapolateThis();
    try {
      double dir= possBalls.getKickDirForResultingAngle(0);
      System.out.println("dir for ang 0: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b1.copy(b);
        b1.predictThisAfterAction(p, kick);
        b1.extrapolate(possBalls.getCycle()-1);
        System.out.println("real result: "+b.getAngleTo(b1));
        list.add(possBalls.getPointForShotAngleAbs(0));
      }
      else {
        System.out.println("dir not possible");
      }
      dir= possBalls.getKickDirForResultingAngle(90);
      System.out.println("dir for ang 90: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b2.copy(b);
        b2.predictThisAfterAction(p, kick);
        b2.extrapolate(possBalls.getCycle()-1);
        System.out.println("real result: "+b.getAngleTo(b2));
        list.add(possBalls.getPointForShotAngleAbs(90));        
      }
      else {
        System.out.println("dir not possible");
      }
      dir= possBalls.getKickDirForResultingAngle(180);
      System.out.println("dir for ang 180: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b3.copy(b);
        b3.predictThisAfterAction(p, kick);
        b3.extrapolate(possBalls.getCycle()-1);
        System.out.println("real result: "+b.getAngleTo(b3));
        list.add(possBalls.getPointForShotAngleAbs(180));   
      }
      else {
        System.out.println("dir not possible");
      }
      dir= possBalls.getKickDirForResultingAngle(-90);     
      System.out.println("dir for ang -90: "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b4.copy(b);
        b4.predictThisAfterAction(p, kick);
        b4.extrapolate(possBalls.getCycle()-1);
        System.out.println("real result: "+b.getAngleTo(b4));
        list.add(possBalls.getPointForShotAngleAbs(-90));        
      }
      else {
        System.out.println("dir not possible");
      }
      dir= possBalls.getKickDirForResultingAngle(needed);
      System.out.println("dir for ang "+needed+": "+dir);
      if (dir != Double.MAX_VALUE) {
        kick.setDirection(dir);
        b5.copy(b);
        b5.predictThisAfterAction(p, kick);
        b5.extrapolate(possBalls.getCycle()-1);
        System.out.println("real result: "+b.getAngleTo(b5));
        list.add(possBalls.getPointForShotAngleAbs(needed));        
      }
      else {
        System.out.println("dir not possible");
      }
      System.out.println();
      System.out.println(p);
      System.out.println(b);
      System.out.println(kick);
      System.out.println(possBalls);
      System.out.println(list);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /** (non-Javadoc)
   * @see robocup.testing.GraphicalTestFrame#paintSituation(java.awt.Graphics)
   */
  @Override
  protected void paintSituation(Graphics g) {
    g.setColor(Color.red);
    drawKickable(g, p);
    drawMovement(g, b);
    drawMovement(g, p);
    g.setColor(Color.YELLOW);
    draw(g,p);
    g.setColor(Color.BLACK);
    draw(g,b);
    g.setColor(Color.blue);
    draw(g,possBalls);
    g.setColor(Color.green);
    draw(g,b1);
    draw(g,b2);
    draw(g,b3);
    draw(g,b4);
    drawMovement(g,b1);
    drawMovement(g,b2);
    drawMovement(g,b3);
    drawMovement(g,b4);
    g.setColor(Color.orange);
    draw(g,b5);
    drawMovement(g,b5);
    draw(g, list);
  }

  /**
   * @param args
   */
  public static void main(String[] args) {
    new TestPoweredBalls();
  }

}
